﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace WorkStation.Frameworks.Core
{
    /// <summary>
    /// * 程序域代理
    /// </summary>
    public class AppDomainProxy : MarshalByRefObject
    {
        /// <summary>
        /// * 回调方法委托
        /// </summary>
        /// <param name="entity">方法参数列表</param>
        public delegate void CallMethodHandle(MethodArgsEntity entity);

        /// <summary>
        /// * 加载程序集
        /// </summary>
        /// <param name="assemblyPath"></param>
        /// <returns></returns>
        public string LoadAssembly(string assemblyPath)
        {
            Assembly i = Assembly.LoadFile(assemblyPath);
            
            return i.FullName;
        }

        /// <summary>
        /// * 在AppDomain执行一个委托方法（经过验证，委托所代理执行的方法如果是static的，则将在子程序域执行，如果不是，则在主程序域执行。）
        /// </summary>
        /// <param name="methodHandle"></param>
        /// <param name="entity"></param>
        public void CallMethod(CallMethodHandle methodHandle, MethodArgsEntity entity)
        {
            if (methodHandle != null) { methodHandle.Invoke(entity); }
        }

        public TResult ExecuteMethod<TResult, TInterface>(Func<TInterface, TResult> func) where TInterface : class
        {
            var type = AppDomain.CurrentDomain.GetAssemblies().Select(v => v.GetTypes().FirstOrDefault(i => i.GetInterface(typeof(TInterface).FullName) == typeof(TInterface)));

            return func.Invoke(Activator.CreateInstance(type.FirstOrDefault()) as TInterface);
        }
    }

    /// <summary>
    /// * 方法参数实体
    /// </summary>
    [Serializable]
    public class MethodArgsEntity
    {
        private Dictionary<string, Object> _args = new Dictionary<string, object>();

        /// <summary>
        /// * 参数列表
        /// </summary>
        public Dictionary<string, object> Args
        {
            get { return this._args; }
            set { this._args = value; }
        }
    }
}
